/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __PQ_GameScene_H__
#define __PQ_GameScene_H__

#include "ClientPrerequisites.h"
#include "SceneObject.h"
#include "UIScreen.h"
#include "Unit.h"

using namespace PQEngine;

namespace PQClient
{
	class IState
	{
	public:
		virtual int getStateId() const = 0 ;
		//
		virtual bool canTransition(IState* targetState) = 0;

		//enter this state
		virtual void enter() = 0;
		virtual void exit() = 0;
	};

	typedef void (*UIHandler)(UIScreen* sender,UIControlID id);

	/*This class represent an integrated logic unit(a kind of state)
	@note	The UI(gui) is an independent system that do nothing with this class.
				We send message(event) to the UI system,to represent game scene change.
	*/
	class GameScene : public PQEngine::Object,
		public OIS::MouseListener,public OIS::KeyListener
	{
	public:
		GameScene(SceneId type,Ogre::SceneType sceneType=Ogre::ST_GENERIC);

		/*Load the game scene by config file.
		@param fileName The name of the config file.
		*/
		void loadScene(Ogre::String fileName);

		/*Load the game scene.
		We already create default scene .(By SceneObject)
		*/
		virtual void loadScene()=0;


		/*Update the game scene
		*/
		virtual void update(float deltaT);

		/*Activate the game scene
		*/
		virtual void activate();

		
		SceneObject* getSceneObject();

		inline SceneId getSceneId()
		{
			return _id;
		}

		void	setState(RunningState state);
		RunningState getState();

		static bool legalSceneId(SceneId id);

		Unit* getUnit(Ogre::String name);

		static GameScene* current()
		{
			return _gameScene;
		}

		/*This function is very important for route the button clicked event.
		@todo It's better to build an event system.
		@param sender The sender of the event
		@param id The id of the event
		*/
		virtual void buttonClicked(UIScreen* sender,UIControlID id)=0;

	protected:
		/*Setup camera by a xml config file
		@param fileName - The name of the config file.
		*/
		void setupCamera(Ogre::String fileName);

		/*Setup camera by a xml config file
		@param fileName - The name of the config file.
		*/
		void setupLights(Ogre::String configFileName);

		/*Setup camera by a xml config file
		@param fileName - The name of the config file.
		*/
		void setupStaticObjects(Ogre::String configFileName);

		/*Setup camera by a xml config file
		@param fileName - The name of the config file.
		*/
		void setupDynamicObjects(Ogre::String configFileName);

		/*Load character unit by a xml config file
		@param unitName - The name of the unit.
		@param fileName - The name of the config file.
		*/
		Unit* loadUnit(Ogre::String name,Unit::Type type);

		Unit* getActiveUnit()
		{
			return _activeUnit;
		}

		void setActiveUnit(Unit* unit)
		{
			_activeUnit=unit;
		}


	protected:
		void setActiveSceneId(SceneId id);
	protected:
		static GameScene* _gameScene;//current active game scene
		SceneObject* _sceneObject;//This scene
		SceneId _id;//current scene id(type)
		bool _loaded;

		std::map<Ogre::String,Unit*> _units;
		Unit* _activeUnit;

	

	};
}
#endif
